const mongoose = require('mongoose');
const crypto = require("crypto");
const validator = require('validator');
const bcrypt = require('bcryptjs');
// 用户模型字段 name  email photo  password passwordConfirm
const userSchema = new mongoose.Schema({
    name: {
        type: String,
        required: [true, 'Please tell as your name']
    },
    email: {
        type: String,
        required: [true, '请提供你的邮箱'],
        unique: true,
        lowercase: true,
        validate: [validator.isEmail, '请提供一个合格的邮箱']
    },
    photo: String,
    role: {
        type: String,
        enum: ['user', 'guide', 'lead-guide', 'admin'],
        default: 'user'
    },
    password: {
        type: String,
        required: [true, '请提供密码'],
        minlength: 8,
        select: false,
    },
    passwordConfirm: {
        type: String,
        required: [true, '请确认输入的密码'],
        validate: {
            validator: function (el) {
                return el === this.password;
            },
            message: "密码不一致"
        }
    },
    passwordChangedAt: Date,
    passwordRestToken: String,
    passwordResetExpires: Date,
    // 假删除账户 实际在数据库中 只是隐藏了 查询的时候检验这个字段即可
    active:{
        type:Boolean,
        default:true,
        select:false,
    }
})
// 密码加密检验
userSchema.pre('save', async function (next) {
    // 当密码被改变的时候才会运行
    if (!this.isModified('password')) return next();

    this.password = await bcrypt.hash(this.password, 12); // 加密

    // 删除确认密码字段 不进入存储
    this.passwordConfirm = undefined; //确认的密码不需要持久化
    next();
})
userSchema.pre('save',function(next){
    if(!this.isModified('password'|| this.isNew)) return next();

    this.passwordChangedAt = Date.now() - 1000; // 数据库存储时间比jwt发送会慢一些
    next();
})
userSchema.pre(/^find/,function(next){
    this.find({active:{$ne:false}});
    next();
})
// 这里相当于挂载一个全局函数给User这个对象上
// 校检密码
userSchema.methods.correctPassword = async function (candidatePassword, userPassword) {
    return await bcrypt.compare(candidatePassword, userPassword)
}
// 改变密码后修改日期
userSchema.methods.changesPasswordAfter = function (JWTTimestamp) {
    if (this.passwordChangedAt) {
        const changedTimestamp = parseInt(this.passwordChangedAt.getTime() / 1000, 10); //10进制
        console.log(changedTimestamp, JWTTimestamp, JWTTimestamp < changedTimestamp, '时间戳');
        return JWTTimestamp < changedTimestamp;
    }
    return false;
}

// 创建重置密码的token
userSchema.methods.createPasswordResetToken = function () {
    const resetToken = crypto.randomBytes(32).toString('hex');
    this.passwordRestToken = crypto.createHash('sha256')
        .update(resetToken)
        .digest('hex');
    this.passwordResetExpires = Date.now() + 10 * 60 * 1000;
    return resetToken
}

const User = mongoose.model('User', userSchema);
module.exports = User;